<template>
	<view class="hot-container">
		<!-- @符号 相当于当前项目的根目录 -->
		<image class="logo" src="@/static/images/logo.png" mode="aspectFit" />
		<view class="search-box">
			<my-search placeholderText="uni app 自定义组件"></my-search>
		</view>
		<view class="tab-sticky">
			<!-- 监听组件中的 @tabClick 事件，调用 onTabClick 方法-->
			<my-tabs :tabData="tabData" :defaultIndex="currentIndex"
				:config="{textColor:'grey',activeTextColor:'orange'}" @tabClick="onTabClick"></my-tabs>
		</view>
		<!-- list 视图 -->
		<!-- 
			1. 使用 mock 数据，构建List的基本结构
			2. 美化样式
			3. 根据 tab 的切换，获取真实数据
			4. 渲染真实数据
			5. 让 list 具备左右切换的能力
			6. 完成 list 与 tabs 联动的能力
		-->
		<!-- current 表示当前展示哪个 swiper-item，不设置的时候，tabIndex一直为0 -->
		<swiper class="swiper" :current="currentIndex" :style="{height:currentSwiperHeight+'px'}"
			@animationfinish="onSwiperEnd" @change="onSwiperChange">
			<!-- swiper 的数量，需要由 tabData 进行决定 -->
			<swiper-item class="swiper-item" v-for="(tabItem,tabIndex) in tabData" :key="tabIndex">
				<view>
					<!-- 加载动画 -->
					<uni-load-more status="loading" v-if="isLoading" />
					<!-- 列表 使用tabIndex-->
					<block v-else>
						<!-- 增加 class 是为了获取 dom 计算 swiper-item 高度-->
						<hot-list-item :class="'hot-list-item-'+tabIndex" v-for="(item,index) in listData[tabIndex]"
							:key="index" :data="item" :ranking="index+1"></hot-list-item>
					</block>
				</view>
			</swiper-item>
		</swiper>
	</view>
</template>

<script>
	import {
		getHotTabs,
		getHotListFromTabType
	} from 'api/hot'

	export default {
		data() {
			return {
				// tabs 数据源
				tabData: [],
				// 激活项
				currentIndex: 0,
				// list 列表数据加载的 loading
				isLoading: true,
				// 列表数据缓存，index 为 key，对应的 list 为 value
				listData: {},
				// 当前 swiper 的高度
				currentSwiperHeight: 0,
				// 保存高度的计算结果，以 index 为key，对应的高度为 value
				swiperHeightData: {},
				// 当前高度
				currentScrollTop:0
			};
		},

		/**
		 * created: 组件实现配置完成，但 dom 未渲染，进行网络请求，配置响应式数据
		 */
		created() {
			this.loadHotTabs();
		},
		/**
		 * 监听页面滚动
		 * @param {Object} res
		 */
		onPageScroll(res){
			this.currentScrollTop = res.scrollTop;
		},

		/**
		 * 所有的方法必须被定义到 methods 中
		 */
		methods: {
			// 获取 热搜文章类型
			async loadHotTabs() {
				// const res = await getHotTabs();
				// this.tabData = res.list;
				console.log("模拟调用接口 getHotTabs")
				this.tabData = [{
							"label": "热榜",
							"id": 0
						}, {
							"label": "前端",
							"id": 1
						},
						{
							"label": "JAVA",
							"id": 2
						}, {
							"label": "PHP",
							"id": 3
						},
						{
							"label": "Python",
							"id": 4
						}, {
							"label": "程序人生",
							"id": 5
						},
						{
							"label": "数据库",
							"id": 6
						}
					],
					// 获取第一页的列表数据
					this.loadHotListFromTab();
			},
			// 获取 list 列表数据
			async loadHotListFromTab() {
				// 改由 onSwiperEnd 判断
				// if (!this.listData[this.currentIndex]) {
				// 1. 如果没有获取到数据
				// 1.1 展示loading
				this.isLoading = true;
				// 1.2 调用接口获取数据
				const id = this.tabData[this.currentIndex].id;
				// 把结果中的 data 数据赋值到 res
				// const {data: res} = await getHotListFromTabType(id);
				console.log("模拟调用接口 getHotListFromTabType id:" + id)
				const {
					data: res
				} = {
					data: {
						list: [{
								"title": id +
									"-123aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
								"desc": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
								"nickname": "张三",
								"views": 1000
							},
							{
								"title": id + "-456cccccccccccc",
								"desc": "bbbbbbbbbbbbbbbbbbbbbbbbb",
								"nickname": "张三",
								"views": 100
							},
							{
								"title": id + "-789ddddddddddddd",
								"desc": "vvvvvvvvvvvvvvvvvvvvvvv",
								"nickname": "张三",
								"views": 10
							},
							{
								"title": id + "-012ffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaf",
								"desc": "dddddddddddddddddd",
								"nickname": "张三",
								"views": 1
							},
							{
								"title": id + "-012ffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaf",
								"desc": "dddddddddddddddddd",
								"nickname": "张三",
								"views": 1
							},
							{
								"title": id + "-012ffffffffffffffffaaaaaaaaaaaaaaaaaaaaaaaaaaaf",
								"desc": "dddddddddddddddddd",
								"nickname": "张三",
								"views": 1
							},
						]
					}
				}
				// 1.3 把数据保存到本地
				this.listData[this.currentIndex] = res.list;
				// 1.4 隐藏 loading
				this.isLoading = false;
				// }
				// else{
				// 2. 已经获取到数据（有缓存）
				// 2.1 直接渲染数据
				// }
				/**
				 * 如何在渲染完成之后触发：
				 * 可以用this.$nextTick()等待渲染完成后执行，但是有兼容性问题；
				 * 使用setTimeout(function() {}, 0)也能实现该效果
				 */
				// 渲染完成数据之后，计算高度
				setTimeout(async () => {
					this.currentSwiperHeight = await this.getCurrentSwiperHeigt();
					// 放入缓存
					this.swiperHeightData[this.currentIndex] = this.currentSwiperHeight;
				}, 0);
			},
			/**
			 * tab 点击事件，会接收到组件中发布事件传递的参数
			 */
			onTabClick(index) {
				this.currentIndex = index;
				// 获取当前 tab 对应的列表（改由swiper动画完成后触发）
				// this.loadHotListFromTab();
			},
			/**
			 * swiper 切换
			 */
			onSwiperChange(e) {
				// 超过130时，tab吸顶，所以以130判断是否吸顶状态
				if (this.currentScrollTop > 130) {
					// 控制列表的滚动位置
					uni.pageScrollTo({
						scrollTop:130
					})
				}
				this.currentIndex = e.detail.current;
			},
			/**
			 * swiper 动画完成
			 */
			onSwiperEnd() {
				// 判断缓存是否存在
				if (!this.listData[this.currentIndex]) {
					this.loadHotListFromTab();
					return;
				}
				// 存在缓存，也存在高度缓存
				this.currentSwiperHeight = this.swiperHeightData[this.currentIndex];
			},
			/**
			 * 计算当前 swiper 的高度
			 */
			getCurrentSwiperHeigt() {
				// 获取 dom 方法是异步的，我们需要做一个Promise
				return new Promise((resolve, reject) => {
					// 累加和
					let sum = 0;
					// 1.拿到所有的 item dom
					const query = uni.createSelectorQuery().in(this);
					query.selectAll(`.hot-list-item-${this.currentIndex}`)
						.boundingClientRect((res) => {
							res.forEach((item) => {
								sum += item.height;
							});
							// 调用成功回调
							resolve(sum);
						})
						.exec();
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	// scoped 表示值在当前组件中生效 增加样式隔离性
	.hot-container {
		background-color: $uni-bg-color;

		.logo {
			width: 100%;
			height: 80px;
		}

		.search-box {
			padding: 0 16px;
			margin-bottom: $uni-spacing-col-base;
		}

		.tab-sticky {
			// position: -webkit-sticky;
			position: sticky;
			z-index: 99;
			// top: 0;
			// uni-app head高度
			top: 44px;
		}
	}
</style>
